package me.kennylee.tongji;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;

/**
 * <p> Gson工具类 </p>
 * <p>Created on 5/11/2017.</p>
 *
 * @author kennylee
 */
public class GsonHelper {

    private static class BooleanAsIntAdapter extends TypeAdapter<Boolean> {
        /**
         * Writes one JSON value (an array, object, string, number, boolean or null)
         * for {@code value}.
         *
         * @param out
         * @param value the Java object to write. May be null.
         */
        @Override
        public void write(JsonWriter out, Boolean value) throws IOException {
            if (value == null) {
                out.nullValue();
            } else {
                out.value(value);
            }
        }

        /**
         * Reads one JSON value (an array, object, string, number, boolean or null)
         * and converts it to a Java object. Returns the converted object.
         *
         * @param in
         * @return the converted Java object. May be null.
         */
        @Override
        public Boolean read(JsonReader in) throws IOException {
            JsonToken peek = in.peek();
            switch (peek) {
                case BOOLEAN:
                    return in.nextBoolean();
                case NULL:
                    in.nextNull();
                    return null;
                case NUMBER:
                    return in.nextInt() != 0;
                case STRING:
                    return Boolean.parseBoolean(in.nextString());
                default:
                    throw new IllegalStateException("Expected BOOLEAN or NUMBER but was " + peek);
            }
        }
    }

    private static final TypeAdapter<Boolean> booleanAsIntAdapter = new BooleanAsIntAdapter();

    public static Gson getBooleanAsIntGson() {
        return new GsonBuilder()
                .registerTypeAdapter(Boolean.class, getBooleanAsIntAdapter())
                .registerTypeAdapter(boolean.class, getBooleanAsIntAdapter())
                .create();
    }

    public static TypeAdapter<Boolean> getBooleanAsIntAdapter() {
        return booleanAsIntAdapter;
    }
}
